package com.ichart.html;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ichart.doc.Api;
import com.ichart.doc.Component;
import com.ichart.doc.ComponentUtils;
import com.ichart.doc.Event;
import com.ichart.doc.Info;
import com.ichart.doc.Item;
import com.ichart.doc.Method;
import com.ichart.html.Template.Html;
import com.ichart.utils.FileUtils;

public class HtmlApi  implements Api{
	
	public Template<Component> pageTemplate =  new PageTemplate();
	public Template<Object> indexTemplate =  new IndexTemplate();
	public Template<Object> topTemplate =  new TopTemplate();
	public Template<List<Component>> referenceTemplate =  new ReferenceTemplate();
	public Template<List<Component>> homeTemplate =  new HomeTemplate();
	
	protected static Map<String,Component> definition = new HashMap<String,Component>();
	
	protected static String ENCODING = "utf-8";
	
	public static void invokeHierarchy(String name,Html html){
		Component c = definition.get(ComponentUtils.getLowerCaseClassName(name));
		List<String> hierarchy = new ArrayList<String>();
		while(c!=null){
			hierarchy.add(c.getName());
			c = definition.get(ComponentUtils.getLowerCaseClassName(c.getExtend()));
		}
		int count = hierarchy.size()-1,j;
		String indent = "<span class='ichartjs_indent'></span>";
		String tree = "<span class='ichartjs_indent'><div class='ichartjs_tree'></div></span>";
		
		html.append("<div class='ichartjs_p_10 ichartjs_m_10 ichartjs_color ichartjs_inline ichartjs_radius5'>");
		html.enter("<div class='ichartjs_font_600 ichartjs_h_25'>");
		html.append(Info.info("Hierarchy"));
		html.enter("</div>");
		
		for (int i=count;i>=0;i--) {
			html.append("<div class='ichartjs_h_18'>");
			j = (count-i);
			while(j>0){
				j--;
				if(j==0){
					html.append(tree);
				}else{
					html.append(indent);
				}
			}
			html.append("<span class='ichartjs_h_18'>");
			html.append(ComponentUtils.getFullLink(hierarchy.get(i)));
			html.enter("</span>");
			
			html.enter("</div>");
		}
		
		html.enterBr("</div>");
	}
	private static int compare(String o1,String o2){
		int length1 = o1.length();   
	    int length2 = o2.length();   
	    int length = length1 > length2 ? length2 : length1;   
	    int c1, c2;   
	    for (int i = 0; i < length; i++) {   
	      c1 = o1.charAt(i);   
	      c2 = o2.charAt(i);   
	      if (c1 > c2) {   
	        return 1;   
	      }else if(c1 < c2) {   
	        return -1;   
	      }  
	    }   
	    if (length1 > length2) {   
	      return 1;   
	    } else if (length1 < length2) {   
	      return -1;   
	    }
	    return 1;   
	}
	
	public static List<Method> getAllMethods(String name){
		List<Method> list = new ArrayList<Method>();
		Component c = definition.get(ComponentUtils.getLowerCaseClassName(name));
		while(c!=null){
			list.addAll(c.getMethods());
			c = definition.get(ComponentUtils.getLowerCaseClassName(c.getExtend()));
		}
		Collections.sort(list,new Comparator<Method>(){
		@Override
		public int compare(Method i1, Method i2) {
		   return HtmlApi.compare(i1.getMethod().toLowerCase(),i2.getMethod().toLowerCase()); 
		}});
		return list;
	}
	
	public static List<Event> getAllEvents(String name){
		List<Event> list = new ArrayList<Event>();
		Component c = definition.get(ComponentUtils.getLowerCaseClassName(name));
		while(c!=null){
			list.addAll(c.getEvents());
			c = definition.get(ComponentUtils.getLowerCaseClassName(c.getExtend()));
		}
		Collections.sort(list,new Comparator<Event>(){
		@Override
		public int compare(Event i1, Event i2) {
		   return HtmlApi.compare(i1.getMethod().toLowerCase(),i2.getMethod().toLowerCase()); 
		}});
		return list;
	}
	
	public static List<Item> getAllItems(String name){
		List<Item> list = new ArrayList<Item>();
		if(name.equals("iChart.Rectangle2D")){
			System.out.println("Rectangle2D");
		}
		Component c = definition.get(ComponentUtils.getLowerCaseClassName(name));
		boolean exist = false;
		while(c!=null){
			/**
			 * 将重复定义的去除
			 */
			for(Item it1:c.getItems()){
				if(OptionFilter.ignore(name, it1.getAttribute())){
					continue;
				}
				for(Item it2:list){
					if(it1.getAttribute().equals(it2.getAttribute())){
						exist = true;
						break;
					}
				}
				if(!exist){
					list.add(it1);
				}
				exist = false;
			}
			
			c = definition.get(ComponentUtils.getLowerCaseClassName(c.getExtend()));
		}
		Collections.sort(list,new Comparator<Item>(){
		@Override
		public int compare(Item i1, Item i2) {
		    return HtmlApi.compare(i1.getAttribute().toLowerCase(),i2.getAttribute().toLowerCase());   
		}});
		
		
		
		return list;
	}
	
	@Override
	public void create(List<Component> components, String directory) {
		this.doParse(components);
		
		for (Component component : components) {
			this.create(component, directory);
		}
		
		this.reference(components, directory);
		this.index(directory);
		this.top(directory);
		this.home(components, directory);
	}
	
	private void doParse(List<Component> components) {
		for (Component component : components) {
			definition.put(ComponentUtils.getLowerCaseClassName(component.getName()),component);
		}
	}
	
	private void create(Component component, String directory) {
		String Html = this.pageTemplate.toHtml(component);
		
		String file = ComponentUtils.getFileName(component.getName());
		System.out.println("Build "+component.getName()+",out file:"+file);
		
		try {
			FileUtils.write(FileUtils.createFile(directory+"html/"+file),Html,ENCODING);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private void home(List<Component> components, String directory) {
		String Html = this.homeTemplate.toHtml(components);
		System.out.println("Build home.html");
		try {
			FileUtils.write(FileUtils.createFile(directory+"html/home.html"),Html,ENCODING);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private void index(String directory) {
		String Html = this.indexTemplate.toHtml(null);
		System.out.println("Build index.html");
		try {
			FileUtils.write(FileUtils.createFile(directory+"index.html"),Html,ENCODING);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	private void top(String directory) {
		String Html = this.topTemplate.toHtml(null);
		System.out.println("Build top.html");
		try {
			FileUtils.write(FileUtils.createFile(directory+"html/top.html"),Html,ENCODING);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	
	private void reference(List<Component> components, String directory) {
		String Html = this.referenceTemplate.toHtml(components);
		System.out.println("Build menu.html");
		try {
			FileUtils.write(FileUtils.createFile(directory+"html/menu.html"),Html,ENCODING);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
